import {
  Component,
  Input,
  Output,
  EventEmitter,
  TemplateRef,
} from '@angular/core';
import { MonthViewDay, CalendarEvent } from 'calendar-utils';
import { isWithinThreshold } from '../../../common/util/util';
import { PlacementArray } from 'positioning';
import { DraggableDirective } from 'angular-draggable-droppable';
import { NgStyle, NgClass, NgTemplateOutlet } from '@angular/common';
import { CalendarTooltipDirective } from '../../../common/calendar-tooltip/calendar-tooltip.directive';
import { ClickDirective } from '../../../common/click/click.directive';
import { CalendarDatePipe } from '../../../common/calendar-date/calendar-date.pipe';
import { CalendarEventTitlePipe } from '../../../common/calendar-event-title/calendar-event-title.pipe';
import { CalendarA11yPipe } from '../../../common/calendar-a11y/calendar-a11y.pipe';

@Component({
  selector: 'mwl-calendar-month-cell',
  template: `
    <ng-template
      #defaultTemplate
      let-day="day"
      let-openDay="openDay"
      let-locale="locale"
      let-tooltipPlacement="tooltipPlacement"
      let-highlightDay="highlightDay"
      let-unhighlightDay="unhighlightDay"
      let-eventClicked="eventClicked"
      let-tooltipTemplate="tooltipTemplate"
      let-tooltipAppendToBody="tooltipAppendToBody"
      let-tooltipDelay="tooltipDelay"
      let-validateDrag="validateDrag"
    >
      <div
        class="cal-cell-top"
        [attr.aria-label]="
          { day: day, locale: locale } | calendarA11y: 'monthCell'
        "
      >
        <span aria-hidden="true">
          @if (day.badgeTotal > 0) {
            <span class="cal-day-badge">{{ day.badgeTotal }}</span>
          }
          <span class="cal-day-number">{{
            day.date | calendarDate: 'monthViewDayNumber' : locale
          }}</span>
        </span>
      </div>
      @if (day.events.length > 0) {
        <div class="cal-events">
          @for (event of day.events; track event.id ?? event) {
            <div
              class="cal-event"
              [ngStyle]="{ backgroundColor: event.color?.primary }"
              [ngClass]="event?.cssClass"
              (mouseenter)="highlightDay.emit({ event: event })"
              (mouseleave)="unhighlightDay.emit({ event: event })"
              [mwlCalendarTooltip]="
                event.title | calendarEventTitle: 'monthTooltip' : event
              "
              [tooltipPlacement]="tooltipPlacement"
              [tooltipEvent]="event"
              [tooltipTemplate]="tooltipTemplate"
              [tooltipAppendToBody]="tooltipAppendToBody"
              [tooltipDelay]="tooltipDelay"
              mwlDraggable
              [class.cal-draggable]="event.draggable"
              dragActiveClass="cal-drag-active"
              [dropData]="{ event: event, draggedFrom: day }"
              [dragAxis]="{ x: event.draggable, y: event.draggable }"
              [validateDrag]="validateDrag"
              [touchStartLongPress]="{ delay: 300, delta: 30 }"
              (mwlClick)="
                eventClicked.emit({ event: event, sourceEvent: $event })
              "
              [attr.aria-hidden]="{} | calendarA11y: 'hideMonthCellEvents'"
            ></div>
          }
        </div>
      }
    </ng-template>
    <ng-template
      [ngTemplateOutlet]="customTemplate || defaultTemplate"
      [ngTemplateOutletContext]="{
        day: day,
        openDay: openDay,
        locale: locale,
        tooltipPlacement: tooltipPlacement,
        highlightDay: highlightDay,
        unhighlightDay: unhighlightDay,
        eventClicked: eventClicked,
        tooltipTemplate: tooltipTemplate,
        tooltipAppendToBody: tooltipAppendToBody,
        tooltipDelay: tooltipDelay,
        validateDrag: validateDrag,
      }"
    />
  `,
  host: {
    class: 'cal-cell cal-day-cell',
    '[class.cal-past]': 'day.isPast',
    '[class.cal-today]': 'day.isToday',
    '[class.cal-future]': 'day.isFuture',
    '[class.cal-weekend]': 'day.isWeekend',
    '[class.cal-in-month]': 'day.inMonth',
    '[class.cal-out-month]': '!day.inMonth',
    '[class.cal-has-events]': 'day.events.length > 0',
    '[class.cal-open]': 'day === openDay',
    '[class.cal-event-highlight]': '!!day.backgroundColor',
  },
  imports: [
    DraggableDirective,
    NgStyle,
    NgClass,
    CalendarTooltipDirective,
    ClickDirective,
    NgTemplateOutlet,
    CalendarDatePipe,
    CalendarEventTitlePipe,
    CalendarA11yPipe,
  ],
})
export class CalendarMonthCellComponent {
  @Input() day: MonthViewDay;

  @Input() openDay: MonthViewDay;

  @Input() locale: string;

  @Input() tooltipPlacement: PlacementArray;

  @Input() tooltipAppendToBody: boolean;

  @Input() customTemplate: TemplateRef<any>;

  @Input() tooltipTemplate: TemplateRef<any>;

  @Input() tooltipDelay: number | null;

  @Output() highlightDay: EventEmitter<any> = new EventEmitter();

  @Output() unhighlightDay: EventEmitter<any> = new EventEmitter();

  @Output() eventClicked = new EventEmitter<{
    event: CalendarEvent;
    sourceEvent: MouseEvent;
  }>();

  validateDrag = isWithinThreshold;
}
